package com.brainydroid.example.numerical_distance;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

import com.brainydroid.framework.Object;
import com.brainydroid.framework.Scene;
import com.brainydroid.framework.Create;



import com.brainydroid.items.Button;
import com.brainydroid.items.Text_box;
import com.brainydroid.items.Time_jauge;


/*
Programming example : Numerical discrimination task
Specification of the task
- 288 trials
- 48 possible number * 6






The aim is to do something very similar to a psychtoolbox.
This means dealing with simple algorithmic (for, while, if)
and hiding the object structure to user



*/

public class ExampleNumDist extends Scene{

	
	//--------------------------------------------- Here Variables must be declared

	int exp_duration;
	int max_exp_duration = 300;

	
	float number_time;
	float blank_time;
		
	int i_sujet;
	String sd_root;

	Button b_right;
	Button b_left;

	Text_box tb_present;
	Text_box tb_feedback;
	Text_box tb_touchpoint;
	
	Time_jauge jauge;
	
	float screen_onset_time;
	float screen_display_time;

	int touched_button;
	int number;
	
	int N_trials_ = 288;

	int ns = 55; // standard  
	
	
	int numbers[]; // = new int[48]; 
    float RT[] = new float[N_trials_+1]; // reaction times
	int A[]  = new int[N_trials_+1]; // actions
	float data[][] = new float[3][N_trials_+1];
	//--------------------------------------------- Here Variables must be declared

	
	/**
	 * Initialize the experiment. This is where objects should be specified and the spritebatch created
	 */
	public void init_experiments() {
		numbers = null;
		while(numbers == null){
		numbers = pseudo_random();
		}
			
		
		Assets.load(); // loading assets for experimets
		Create.init(this); // Initializing item creation
		
		
		// Item creation  
		b_left = Create.newButton(10f, 10f,   300f, 150f, 0);
		b_right = Create.newButton(485f, 10f, 300f, 150f, 0);
		
		b_left.setTxtreg(Assets.test_texture_r);
		b_right.setTxtreg(Assets.test_texture_r);
		
		
		tb_present = Create.newText_box(320, 400, "7", 0);

		//tb_feedback = Create.newText_box(50, 400, "Correct", 0);
		tb_feedback = Create.newText_box(200, 400, "Correct", 0);

		tb_touchpoint = Create.newText_box(400, 400, "", 0);
				
		tb_present.setfont(Assets.font);
		tb_feedback.setfont(Assets.font);
		tb_touchpoint.setfont(Assets.font);
		
		
		// Initializing variables for first trial
		i_screen_ = 1;
		i_trial_ = 1;
		
		number_time = 1f;
		blank_time = 1.5f;
		
		screen_onset_time = getTime();
		screen_display_time = 1;
		
		b_right.show();
		b_left.show();
		tb_present.show();
		tb_feedback.hide();

		tb_touchpoint.setText(sd_root);// "100,100";
		tb_touchpoint.hide();
		
		touched_button = 0;
		number = 0;
		
		number = numbers[i_trial_];
		tb_present.setText(Integer.toString(number));
		
		setTime(0f);
		screen_onset_time = getTime() + 3; // adds 3 sec before start
		
		jauge = Create.newTimejauge(10f, 460f, 790f, 10f,getTime(), 300f);
		jauge.show();
		
		screen_display_time = 2;
	}

	
	
	public void experiment_loop(){
		
		System.out.println("time :"+ getTime());
		System.out.println("duration :"+ exp_duration);

		
		if ((i_trial_> N_trials_-1)||(getTime()>(float)exp_duration)){
			try {
				end_of_exp();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}   
		   
		
		
		

		
		//
		// _______ first screen : digit presentation
		if (i_screen_ == 1){
			
			
			// manage touch event
			if (b_left.checktouched()){
				b_right.hide(); 
				touched_button = 1;
				
				if ((number>ns)){
					Assets.wrong.play();
				}
				
				RT[i_trial_-1] = getTime() - screen_onset_time;
				A[i_trial_-1] = 1;
				}
			if (b_right.checktouched()){
				b_left.hide();  touched_button = 2;
				
				if ((number<ns)){
					Assets.wrong.play();
				}

				RT[i_trial_-1] = getTime() - screen_onset_time;
				A[i_trial_-1] = 2;
				}
			
			// manage transitions
			if ((getTime()> screen_onset_time+blank_time)){
				i_screen_ = 2;
				screen_onset_time = getTime();
				screen_display_time = 2;
				b_right.hide();
				b_left.hide();
				tb_present.hide();
			//	tb_feedback.show();
				

				tb_feedback.setText(" Wrong"); // default

				if ((number<ns) & (touched_button == 1)){
					tb_feedback.setText("Correct");
				}else if ((number>ns) & (touched_button == 2)){
					tb_feedback.setText("Correct");
				} else{
					tb_feedback.setText(" Wrong"); // default
				}	
				
				
			}
			
		// _______ second screen : feedback presentation	
		}else if(i_screen_ == 2){
			
			// manage transition
			if (getTime()> screen_onset_time+number_time){
				i_screen_ = 1;
				screen_onset_time = getTime();
				screen_display_time = 2;
				b_right.show();
				b_left.show();
				tb_present.show();
				tb_feedback.hide();
				
				i_trial_ += 1;
				
				number = numbers[i_trial_];
				tb_present.setText(Integer.toString(number));

				
				}
			
		}
	}

  

	
	
	/**
	 * Setting the experiment duration
	 * @param exp_d
	 */
	public ExampleNumDist(int exp_d) {
		exp_duration = exp_d; 
		// TODO Auto-generated constructor stub
	}
	
	
	/**
	 * If no info about duration, duration is set to maximum value
	 */
	public ExampleNumDist() {
		// TODO Auto-generated constructor stub
		exp_duration = max_exp_duration;
	}
	


	public void end_of_exp() throws IOException{

		float data[][] = new float[3][i_trial_+1];

	// filling data
		for (int i = 0 ; i<i_trial_; i++){
			data[0][i] = (float)numbers[i];
			data[1][i] = (float)RT[i];
			data[2][i] = (float)A[i];
		}
		
		String[] head = new String[3]; 
		head[0]=new String ("number"); 
		head[1]=new String ("delay"); 
		head[2]=new String ("answer"); 
		
		data2sd.storedata(head,data);
		dispose();

		

	}



	@Override
	public void resize(int width, int height) {
		// TODO Auto-generated method stub
		
	}

	public int[] pseudo_random(){

		ArrayList<Integer> numbers = new ArrayList<Integer>(); 
		for (int i = 31;i<80;i++){ //31-80
			if (!(i==55)){
				numbers.add(i);
			}
		}

		// concatenate numbers list
		int n_rep = 6;
		ArrayList<Integer> n_r = new ArrayList<Integer>(); 
		for (int i = 0;i<n_rep;i++){
			n_r.addAll(numbers);
		}

		//System.out.println("initial list :"+ n_r);

		Collections.shuffle(n_r);
		//System.out.println("after first shuffle :"+ n_r);

		ArrayList<Integer> n_r_prand = new ArrayList<Integer>(); 


		boolean cond1 = true;
		boolean cond2 = false;
		int N =n_r.size();

		n_r_prand.add(n_r.get(0));
		n_r.remove(0);
		for (int i = 1;i<N;i++){

			n_r_prand.add(n_r.get(0));
			cond1 =  (n_r_prand.get(i)==n_r_prand.get(i-1));
			if (i>1){
				cond2 = ((n_r_prand.get(i)<55)&&(n_r_prand.get(i-1)<55)&&(n_r_prand.get(i-2)<55))||((n_r_prand.get(i)>55)&&(n_r_prand.get(i-1)>55)&&(n_r_prand.get(i-2)>55));
		//		System.out.println("i-2 :"+ n_r_prand.get(i-2));

			}			
	//		System.out.println("i-1 :"+ n_r_prand.get(i-1));
//			System.out.println("i :"+ n_r_prand.get(i));

			int i_shuf = 0;
			while (cond1||cond2){
				Collections.shuffle(n_r);
				n_r_prand.set(i, n_r.get(0));
				cond1 = (n_r_prand.get(i)==n_r_prand.get(i-1));					
				if (i>1){
					cond2 = ((n_r_prand.get(i)<55)&&(n_r_prand.get(i-1)<55)&&(n_r_prand.get(i-2)<55))||((n_r_prand.get(i)>55)&&(n_r_prand.get(i-1)>55)&&(n_r_prand.get(i-2)>55));
	//				System.out.println("i-2 :"+ n_r_prand.get(i-2));

				}	
	//			System.out.println("i-1 :"+ n_r_prand.get(i-1));
	//			System.out.println("i :"+ n_r_prand.get(i));
				//if (cond2){System.out.println("bad2");}
				//if (cond1){System.out.println("bad1");}

				i_shuf++;
				if (i_shuf == 20){return null;}

			}

			n_r.remove(0);

		}

		System.out.println("pseudo randomization :"+ n_r_prand);

		// return an array
		int n[] = new int[n_r_prand.size()]; 
		for (int i = 0;i<n.length;i++){
			n[i] = n_r_prand.get(i);
		}
		
		return n;
	}

	
	
	

}
